package workpool

import (
	"log"
)

//worker 实际处理Job的工作者
type worker struct {
	id         string       //唯一ID
	workerPool chan JobChan //用于将JobChannel送入WorkerPool 供调度器WorkerPool进行分发
	jobs       JobChan      //当前Worker接收待处理Job的管道
	quit       chan bool
}

func (w *worker) Id() string {
	return w.id
}

func newWorker(id string, workerPool chan JobChan) *worker {
	return &worker{
		id:         id,
		workerPool: workerPool,
		jobs:       make(JobChan),
		quit:       make(chan bool),
	}
}

// start 开启一个 worker 循环，监听退出 channel，可按需停止这个循环
func (w *worker) start() {
	go func() {
		for {
			if w.execJob() {
				break
			}
		}
	}()
}

func (w *worker) execJob() bool {
	var job Job
	defer func() {
		if e := recover(); e != nil {
			if job != nil {
				log.Printf("Worker:%v Job:%v Recover:%v\n", w.id, job.GetId(), e)
			}
		}
	}()
	// 将当前的 worker 注册到 调度器的队列中
	// 之后每次处理完一个任务就会重新注册 以供调度
	w.workerPool <- w.jobs
	select {
	case job = <-w.jobs:
		err := job.Exec()
		if err != nil {
			log.Printf("Worker:%v Job:%v Err:%v\n", w.id, job.GetId(), err)
		} else {
			log.Printf("Worker:%v Job:%v Success\n", w.id, job.GetId())
		}
		return false
	case <-w.quit:
		log.Printf("Worker:%v Stop \n", w.id)
		return true
	}
}

//stop 停止工作者，正在执行的job结束后才会停止
func (w *worker) stop() {
	w.quit <- true
}
